package fr.isen.web.webservicetemp.Dao;

import fr.isen.web.webservicetemp.Entity.Data;

import java.text.DateFormat;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import org.hibernate.Query;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
import org.springframework.transaction.annotation.Transactional;
import sun.security.jca.GetInstance;

/**
 *
 * @authors Maistre Louis, louis madeuf
 */
public class DataAccessObject extends HibernateDaoSupport implements DataAccessObjectInterface {

    @Override
    public List<Data> getAllData() {
        return getHibernateTemplate().find("from Data");
    }

    @Override
    public List<Data> getDataBetween(Date startDate, Date endDate) {
        Data testBourrage = new Data();
        testBourrage.setDateCapture(new Date());
        addData(testBourrage);

        Query query = getSession().createQuery("from Data as data where datecapture >= ? AND datecapture <= ?");
        query.setDate(0, startDate);
        query.setDate(1, endDate);

        return query.list();
    }

    @Override
    public Data addData(Data data) {
        return (Data) (getDataFromId(((Long) getHibernateTemplate().save(data))));
    }

    @Override
    public void addDatas(List<Data> datas) {
        Iterator it = datas.iterator();
        //getHibernateTemplate().saveOrUpdateAll(datas);
        while (it.hasNext()) {
            Data data = (Data) it.next();
            this.addData(data);
        }
    }

    @Override
    public void deleteData(Data data) {
        getHibernateTemplate().delete(data);
    }

    @Override
    public void deleteDataById(long id) {
        Query query = getSession().createQuery("delete from Data as data where id = ?");
        query.setParameter(0, id);

        int rowCount = query.executeUpdate();
        System.out.println("Nombre de valeurs sup: " + rowCount);
    }

    @Override
    public Data getDataFromId(long id) {
        return (Data) getHibernateTemplate().find("from Data as data where data.id = ?", id).get(0);
    }

    @Override
    public Data updateData(Data data) {
        getHibernateTemplate().update(data);
        return (Data) getDataFromId(data.getId());
    }

    @Override
    public Boolean hasATwin(String location, Date date) {
        DateFormat df1 = new SimpleDateFormat("yyyyMMdd");
        List<Data> testList = getHibernateTemplate().find("from Data as data where data.location = ?", location);
        if ((testList != null) && (!testList.isEmpty())) {
            int k = 0;
            while (testList.size() > k) {
                if (df1.format(testList.get(k).getDateCapture()).equalsIgnoreCase(df1.format(date))) {
                    return true;
                }
                k++;
            }
        }
        return false;
    }

    @Override
    public List<String> getLocation() {

        return getHibernateTemplate().find("select distinct data.location from Data data");
    }

    @Override
    public List<Data> getDataView2DYears(Date date, String Location) {
        Query query = getSession().createQuery("from Data as data where datecapture >= ? AND datecapture <= ? AND data.location = ?");
       
            
            ArrayList<Data> data2d = new ArrayList<Data>();
            ArrayList<Data> value = new ArrayList<Data>();
           
            Calendar startDate = Calendar.getInstance();
            Calendar endDate = Calendar.getInstance();
            startDate.setTime(date);
            startDate.set(Calendar.DAY_OF_MONTH, 1);
            startDate.set(Calendar.MONTH, 0);
            endDate.setTime(date);
            endDate.set(Calendar.DAY_OF_MONTH, 31);
            endDate.set(Calendar.MONTH, 11);
            System.out.println(startDate + "  " + endDate);
            query.setDate(0, startDate.getTime());
            query.setDate(1, endDate.getTime());
            query.setString(2, Location);
            value = (ArrayList<Data>) query.list();
            Calendar tempCalendar =Calendar.getInstance();
            for (int i = 0; i < 12; i++) { 
              Data temp = new Data();
              startDate.set(Calendar.MONTH, i);
            temp.setDateCapture(startDate.getTime());
            ArrayList<Data> valueMonth = new ArrayList<Data>();
            for(int j=0;j<value.size();j++)
            {
                
                tempCalendar.setTime(value.get(j).getDateCapture());
                if(tempCalendar.get(Calendar.MONTH)==i)
                {
                    valueMonth.add(value.get(j));
                }
            }
            temp.setDataValue(averageTemperature(valueMonth));
            System.out.println(temp.getDataValue() + "   " + temp.getDateCapture());
            data2d.add(temp);
        }


        return data2d;
    }

    @Override
    public List<Data> getDataView2DMonth(Date date, String Location) {
        Query query = getSession().createQuery("from Data as data where datecapture >= ? AND datecapture < ? AND data.location = ?");
        ArrayList<Data> data2d = new ArrayList<Data>();

        int[] NumberOfDay = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
        
            ArrayList<Data> value = new ArrayList<Data>();
            
            Calendar startDate = Calendar.getInstance();
            Calendar endDate = Calendar.getInstance();
            startDate.setTime(date);
            startDate.set(Calendar.DAY_OF_MONTH, 1);
            endDate.setTime(date);
            endDate.set(Calendar.DAY_OF_MONTH, NumberOfDay[startDate.get(Calendar.MONTH)]);

            System.out.println(startDate + "  " + endDate);
            query.setDate(0, startDate.getTime());
            query.setDate(1, endDate.getTime());
            query.setString(2, Location);
            value = (ArrayList<Data>) query.list();
             Calendar tempCalendar =Calendar.getInstance();
            for (int i = 1; i < NumberOfDay[startDate.get(Calendar.MONTH)] + 1; i++) {
                Data temp = new Data();
                startDate.set(Calendar.DAY_OF_MONTH, i);
            temp.setDateCapture(startDate.getTime());
            ArrayList<Data> valueDay = new ArrayList<Data>();
           
            for(int j=0;j<value.size();j++)
            {
                
                tempCalendar.setTime(value.get(j).getDateCapture());
                if(tempCalendar.get(Calendar.DAY_OF_MONTH)==i)
                {
                    valueDay.add(value.get(j));
                }
            }
            temp.setDataValue(averageTemperature(valueDay));
            System.out.println(temp.getDataValue() + "   " + temp.getDateCapture());
            data2d.add(temp);
        }


        return data2d;
    }

    @Override
    public List<Data> getDataView2DDay(Date date, String Location) {
        Query query = getSession().createQuery("from Data as data where datecapture >= ? AND datecapture <= ? AND data.location = ? ORDER BY datecapture");
        ArrayList<Data> data2d = new ArrayList<Data>();


        ArrayList<Data> value = new ArrayList<Data>();
        Data temp = new Data();

        Calendar startDate = Calendar.getInstance();
        Calendar endDate = Calendar.getInstance();
        startDate.setTime(date);
        endDate.set(Calendar.DATE, startDate.get(Calendar.DAY_OF_MONTH) + 1);

        endDate.set(Calendar.MONTH, startDate.get(Calendar.MONTH));
        endDate.set(Calendar.YEAR, startDate.get(Calendar.YEAR));

        System.out.println(startDate + "  " + endDate);
        query.setDate(0, startDate.getTime());
        query.setDate(1, endDate.getTime());
        query.setString(2, Location);

        return query.list();
    }

    public float averageTemperature(ArrayList<Data> value) {
        DecimalFormat df = new DecimalFormat("0.00");
        float temps = 0;
        for (int i = 0; i < value.size(); i++) {
            temps += value.get(i).getDataValue();

        }
        return (float) floor(temps / (value.size() + 1), 2);
    }

    public double floor(float a, int n) {
        double p = Math.pow(10.0, n);
        return Math.floor((a * p) + 0.5) / p;
    }

    @Override
    public void deleteDatabase() {
        Query query = getSession().createQuery("delete from Data ");
        int rowCount = query.executeUpdate();
        System.out.println("Nombre de valeurs sup: " + rowCount);
    }
}
